home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / editors / mjovesrc.zoo / fmt.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  8KB  |  439 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "fp.h"
  10. #include "termcap.h"
  11. #include "ctype.h"
  12. #include "disp.h"
  13.  
  14. #ifdef    MAC
  15. # include  "mac.h"
  16. #else
  17. # ifdef    STDARGS
  18. #  include <stdarg.h>
  19. # else
  20. #  include <varargs.h>
  21. # endif
  22. #endif
  23.  
  24. private void
  25.     doformat proto((File *, const char *, va_list)),
  26.     outld proto((long, int)),
  27.     pad proto((int, int));
  28.  
  29. char    mesgbuf[MESG_SIZE];
  30.  
  31. void
  32. format(buf, len, fmt, ap)
  33. char    *buf;
  34. const char    *fmt;
  35. size_t    len;
  36. va_list    ap;
  37. {
  38.     File    strbuf;
  39.  
  40.     strbuf.f_ptr = strbuf.f_base = buf;
  41.     strbuf.f_fd = -1;        /* Not legit for files */
  42.     strbuf.f_bufsize = strbuf.f_cnt = len;
  43.     strbuf.f_flags = F_STRING;
  44.  
  45.     doformat(&strbuf, fmt, ap);
  46.     jputc('\0', &strbuf);    /* jputc will place this, even if overflow */
  47. }
  48.  
  49. #ifdef    IBMPC
  50. int    specialmap = 0,    /* ??? never used? -- DHR */
  51.     specialkey = 0;
  52.  
  53. #define Empty ""
  54.  
  55. const char *const altseq[133] = {
  56. Empty, Empty, Empty, "Ctrl-@", Empty, Empty, Empty, Empty,
  57. Empty, Empty, Empty, Empty, Empty, Empty, Empty, "Left",
  58. "Alt-Q", "Alt-W", "Alt-E", "Alt-R", "Alt-T", "Alt-Y", "Alt-U", "Alt-I",
  59. "Alt-O", "Alt-P", Empty, Empty, Empty, Empty, "Alt-A", "Alt-S",
  60. "Alt-D", "Alt-F", "Alt-G", "Alt-H", "Alt-J", "Alt-K", "Alt-L", Empty,
  61. Empty, Empty, Empty, Empty, "Alt-Z", "Alt-X", "Alt-C", "Alt-V",
  62. "Alt-B", "Alt-N", "Alt-M", Empty, Empty, Empty, Empty, Empty,
  63. Empty, Empty, Empty, "F1", "F2", "F3", "F4", "F5",
  64. "F6", "F7", "F8", "F9", "F10", Empty, Empty, "Home",
  65. "Up", "PageUp", Empty, "Left", Empty, "Right", Empty, "End",
  66. "Down", "PageDown", "Ins", "Del", "Shift F1", "Shift F2", "Shift F3", "Shift F4",
  67. "Shift F5", "Shift F6", "Shift F7", "Shift F8", "Shift F9", "Shift F10", "Ctrl F1", "Ctrl F2",
  68. "Ctrl F3", "Ctrl F4", "Ctrl F5", "Ctrl F6", "Ctrl F7", "Ctrl F8", "Ctrl F9", "Ctrl F10",
  69. "Alt F1", "Alt F2", "Alt F3", "Alt F4", "Alt F5", "Alt F6", "Alt F7", "Alt F8",
  70. "Alt F9", "Alt F10", "Ctrl PrtSc", "Ctrl Left", "Ctrl Right", "Ctrl End", "Ctrl PageDown", "Ctrl Home",
  71. "Alt 1", "Alt 2", "Alt 3", "Alt 4", "Alt 5", "Alt 6", "Alt 7", "Alt 8",
  72. "Alt 9", "Alt 0", "Alt Minus", "Alt Equals", "Ctrl PageUp"
  73. };
  74. #endif
  75.  
  76.  
  77. private void
  78. PPchar(c, str, size)
  79. int    c;
  80. char    *str;
  81. size_t    size;
  82. {
  83.     char    *cp = str;
  84.  
  85. #ifdef    IBMPC
  86.     if (specialmap || specialkey) {
  87.         if (c < 0 || c > 132)
  88.             c = 0;
  89.         strcpy(cp, altseq[c]);
  90.     } else if (c == '\377') {
  91.         *cp = '\0';    /* this character was invisible */
  92.     } else
  93. #endif
  94.     if (c == '\033') {
  95.         strcpy(cp, "ESC");
  96.     } else if (c < ' ') {
  97.         swritef(cp, size, "C-%c", c + '@');
  98.     } else if (c == '\177') {
  99.         strcpy(cp, "^?");
  100.     } else {
  101.         swritef(cp, size, "%c", c);
  102.     }
  103. }
  104.  
  105. private struct fmt_state {
  106.     int    precision,
  107.         width,
  108.         leftadj;
  109.     char    padc;
  110.     File    *iop;
  111. } current_fmt;
  112.  
  113. private void
  114. putld(d, base)
  115. long    d;
  116. int    base;
  117. {
  118.     int    len = 1;
  119.     long    tmpd = d;
  120.  
  121.     if (current_fmt.width == 0 && current_fmt.precision) {
  122.         current_fmt.width = current_fmt.precision;
  123.         current_fmt.padc = '0';
  124.     }
  125.     while ((tmpd = (tmpd / base)) != 0)
  126.         len += 1;
  127.     if (d < 0)
  128.         len += 1;
  129.     if (!current_fmt.leftadj)
  130.         pad(current_fmt.padc, current_fmt.width - len);
  131.     if (d < 0) {
  132.         jputc('-', current_fmt.iop);
  133.         d = -d;
  134.     }
  135.     outld(d, base);
  136.     if (current_fmt.leftadj)
  137.         pad(current_fmt.padc, current_fmt.width - len);
  138. }
  139.  
  140. private void
  141. outld(d, base)
  142. long    d;
  143. int    base;
  144. {
  145.     register long    n;
  146.     static const char    chars[] = {'0', '1', '2', '3', '4', '5', '6',
  147.                     '7', '8', '9', 'a', 'b', 'c', 'd',
  148.                     'e', 'f'};
  149.  
  150.     if ((n = (d / base)) != 0)
  151.         outld(n, base);
  152.     jputc((int) (chars[(int) (d % base)]), current_fmt.iop);
  153. }
  154.  
  155. private void
  156. jputs(str)
  157. char    *str;
  158. {
  159.     int    len;
  160.     register char    *cp;
  161.  
  162.     if (str == NULL)
  163.         str = "(null)";
  164.     len = strlen(str);
  165.     if (current_fmt.precision == 0 || len < current_fmt.precision)
  166.         current_fmt.precision = len;
  167.     else
  168.         len = current_fmt.precision;
  169.     cp = str;
  170.     if (!current_fmt.leftadj)
  171.         pad(' ', current_fmt.width - len);
  172.     while (--current_fmt.precision >= 0)
  173.         jputc(*cp++, current_fmt.iop);
  174.     if (current_fmt.leftadj)
  175.         pad(' ', current_fmt.width - len);
  176. }
  177.  
  178. private void
  179. pad(c, amount)
  180. register int    c,
  181.         amount;
  182. {
  183.     while (--amount >= 0)
  184.         jputc(c, current_fmt.iop);
  185. }
  186.  
  187. private void
  188. doformat(sp, fmt, ap)
  189. register File    *sp;
  190. register const char    *fmt;
  191. va_list    ap;
  192. {
  193.     register char    c;
  194.     struct fmt_state    prev_fmt;
  195.  
  196.     prev_fmt = current_fmt;
  197.     current_fmt.iop = sp;
  198.  
  199.     while ((c = *fmt++) != '\0') {
  200.         if (c != '%') {
  201.             jputc(c, current_fmt.iop);
  202.             continue;
  203.         }
  204.  
  205.         current_fmt.padc = ' ';
  206.         current_fmt.precision = current_fmt.leftadj = current_fmt.width = 0;
  207.         c = *fmt++;
  208.         if (c == '-') {
  209.             current_fmt.leftadj = YES;
  210.             c = *fmt++;
  211.         }
  212.         if (c == '0') {
  213.             current_fmt.padc = '0';
  214.             c = *fmt++;
  215.         }
  216.         while (c >= '0' && c <= '9') {
  217.             current_fmt.width = current_fmt.width * 10 + (c - '0');
  218.             c = *fmt++;
  219.         }
  220.         if (c == '*') {
  221.             current_fmt.width = va_arg(ap, int);
  222.             c = *fmt++;
  223.         }
  224.         if (c == '.') {
  225.             c = *fmt++;
  226.             while (c >= '0' && c <= '9') {
  227.                 current_fmt.precision = current_fmt.precision * 10 + (c - '0');
  228.                 c = *fmt++;
  229.             }
  230.             if (c == '*') {
  231.                 current_fmt.precision = va_arg(ap, int);
  232.                 c = *fmt++;
  233.             }
  234.         }
  235.     reswitch:
  236.         /* At this point, fmt points at one past the format letter. */
  237.         switch (c) {
  238.         case '%':
  239.             jputc('%', current_fmt.iop);
  240.             break;
  241.  
  242.         case 'O':
  243.         case 'D':
  244.         case 'X':
  245.             putld(va_arg(ap, long), (c == 'O') ? 8 :
  246.                         (c == 'D') ? 10 : 16);
  247.             break;
  248.  
  249.         case 'b':
  250.             {
  251.             Buffer    *b = va_arg(ap, Buffer *);
  252.  
  253.             jputs(b->b_name);
  254.             break;
  255.             }
  256.  
  257.         case 'c':
  258.             jputc(va_arg(ap, int), current_fmt.iop);
  259.             break;
  260.  
  261.         case 'o':
  262.         case 'd':
  263.         case 'x':
  264.             putld((long) va_arg(ap, int), (c == 'o') ? 8 :
  265.                         (c == 'd') ? 10 : 16);
  266.             break;
  267.  
  268.         case 'f':    /* current command name gets inserted here! */
  269.             jputs(LastCmd->Name);
  270.             break;
  271.  
  272.         case 'l':
  273.             c = CharUpcase(*++fmt);
  274.             goto reswitch;
  275.  
  276.         case 'n':
  277.             if (va_arg(ap, int) != 1)
  278.                 jputs("s");
  279.             break;
  280.  
  281.         case 'p':
  282.             {
  283.             char    cbuf[20];
  284.  
  285.             PPchar(va_arg(ap, int), cbuf, sizeof(cbuf));
  286.             jputs(cbuf);
  287.             break;
  288.             }
  289.  
  290.         case 's':
  291.             jputs(va_arg(ap, char *));
  292.             break;
  293.  
  294.         default:
  295.             complain("Unknown format directive: \"%%%c\"", c);
  296.         }
  297.     }
  298.     current_fmt = prev_fmt;
  299. }
  300.  
  301. #ifdef    STDARGS
  302. char *
  303. sprint(const char *fmt, ...)
  304. #else
  305. /*VARARGS1*/ char *
  306. sprint(fmt, va_alist)
  307.     const char    *fmt;
  308.     va_dcl
  309. #endif
  310. {
  311.     va_list    ap;
  312.     static char    line[100];
  313.  
  314.     va_init(ap, fmt);
  315.     format(line, sizeof line, fmt, ap);
  316.     va_end(ap);
  317.     return line;
  318. }
  319.  
  320. #ifdef    STDARGS
  321. void
  322. writef(const char *fmt, ...)
  323. #else
  324. /*VARARGS1*/ void
  325. writef(fmt, va_alist)
  326.     const char    *fmt;
  327.     va_dcl
  328. #endif
  329. {
  330.     va_list    ap;
  331.  
  332.     va_init(ap, fmt);
  333. #ifndef    IBMPC
  334.     doformat(stdout, fmt, ap);
  335. #else    /* IBMPC */
  336.     write_em(sprint(fmt, ap));
  337.     /* doformat(stdout, fmt, ap); */
  338. #endif    /* IBMPC */
  339.     va_end(ap);
  340. }
  341.  
  342. #ifdef    STDARGS
  343. void
  344. fwritef(File *fp, const char *fmt, ...)
  345. #else
  346. /*VARARGS2*/ void
  347. fwritef(fp, fmt, va_alist)
  348.     File    *fp;
  349.     const char    *fmt;
  350.     va_dcl
  351. #endif
  352. {
  353.     va_list    ap;
  354.  
  355.     va_init(ap, fmt);
  356.     doformat(fp, fmt, ap);
  357.     va_end(ap);
  358. }
  359.  
  360. #ifdef    STDARGS
  361. void
  362. swritef(char *str, size_t size, const char *fmt, ...)
  363. #else
  364. /*VARARGS3*/ void
  365. swritef(str, size, fmt, va_alist)
  366.     char    *str;
  367.     size_t    size;
  368.     const char    *fmt;
  369.     va_dcl
  370. #endif
  371. {
  372.     va_list    ap;
  373.  
  374.     va_init(ap, fmt);
  375.     format(str, size, fmt, ap);
  376.     va_end(ap);
  377. }
  378.  
  379. #ifdef    STDARGS
  380. void
  381. s_mess(const char *fmt, ...)
  382. #else
  383. /*VARARGS1*/ void
  384. s_mess(fmt, va_alist)
  385.     const char    *fmt;
  386.     va_dcl
  387. #endif
  388. {
  389.     va_list    ap;
  390.  
  391.     if (InJoverc)
  392.         return;
  393.     va_init(ap, fmt);
  394.     format(mesgbuf, sizeof mesgbuf, fmt, ap);
  395.     va_end(ap);
  396.     message(mesgbuf);
  397. }
  398.  
  399. #ifdef    STDARGS
  400. void
  401. f_mess(const char *fmt, ...)
  402. #else
  403. /*VARARGS1*/ void
  404. f_mess(fmt, va_alist)
  405.     const char    *fmt;
  406.     va_dcl
  407. #endif
  408. {
  409.     va_list    ap;
  410.  
  411.     va_init(ap, fmt);
  412.     format(mesgbuf, sizeof mesgbuf, fmt, ap);
  413.     va_end(ap);
  414.     DrawMesg(NO);
  415.     errormsg = NO;
  416.     UpdMesg = YES;    /* still needs updating (for convenience) */
  417. }
  418.  
  419. #ifdef    STDARGS
  420. void
  421. add_mess(const c